package com.mjf.cjt.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mjf.cjt.domain.TProductReceivePush;
import com.mjf.cjt.domain.TProductReceivePushDetails;
import com.mjf.cjt.mapper.TProductReceivePushMapper;
import com.mjf.cjt.service.AsyncTMService;
import com.mjf.cjt.service.TProductReceiveDetailsPushService;
import com.mjf.cjt.service.TProductReceivePushService;
import com.mjf.cjt.vo.ProductReceiveCreateVO;
import com.mjf.cjt.vo.ProductReceiveListVO;
import com.mjf.cjt.vo.ProductReceiveQueryParam;
import com.mjf.cjt.vo.TFResultVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * desc
 * </p>
 *
 * @author chenshoumeng
 * @date 2025/7/27 16:08
 */
@Slf4j
@Service
public class TProductReceivePushServiceImpl extends ServiceImpl<TProductReceivePushMapper, TProductReceivePush> implements TProductReceivePushService {

    @Autowired
    private TProductReceiveDetailsPushService tProductReceiveDetailsPushService;
    @Autowired
    private AsyncTMService asyncTMService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void pushProductReceive(String start, String end) {
        List<TProductReceivePush> list = list(Wrappers.<TProductReceivePush>lambdaQuery()
            .ge(StrUtil.isNotBlank( start), TProductReceivePush::getCreateTime, start)
            .le(StrUtil.isNotBlank( end), TProductReceivePush::getCreateTime, end)
            .eq(TProductReceivePush::getPushStatus, 0)
        );
        pushProductReceive(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void pushProductReceiveByIds(List<String> ids) {
        List<TProductReceivePush> list = list(Wrappers.<TProductReceivePush>lambdaQuery()
            .eq(TProductReceivePush::getPushStatus, 0)
            .in(TProductReceivePush::getId, ids));
        pushProductReceive(list);
    }

    @Override
    public Page<ProductReceiveListVO> queryProductReceive(ProductReceiveQueryParam param) {

        Page<ProductReceiveListVO> page = new Page<>(param.getPage(), param.getSize());
        page.setTotal(0);
        page.setRecords(new ArrayList<>());
        LambdaQueryWrapper<TProductReceivePush> qw = Wrappers.<TProductReceivePush>lambdaQuery()
            .ge(StrUtil.isNotBlank(param.getStart()), TProductReceivePush::getCreateTime, param.getStart())
            .le(StrUtil.isNotBlank(param.getEnd()), TProductReceivePush::getCreateTime, param.getEnd())
            ;
        long count = count(qw);
        page.setTotal(count);
        qw.orderByDesc(TProductReceivePush::getCreateTime);
        qw.last("limit " + (param.getPage() - 1) * param.getSize() + "," + param.getSize());

        List<TProductReceivePush> list = list(qw);

        page.setRecords(list.stream().map(item -> ProductReceiveListVO.builder()
            .id(item.getId())
            .externalCode(item.getExternalCode())
            .voucherTypeCode(item.getVoucherTypeCode())
            .voucherDate(item.getVoucherDate())
            .busiTypeCode(item.getBusiTypeCode())
            .rdStyleCode(item.getRdStyleCode())
            .warehouseCode(item.getWarehouseCode())
            .createTime(item.getCreateTime())
            .pushStatus(item.getPushStatus())
            .pushTime(item.getPushTime())
            .pushResult(item.getPushResult())
            .pushId(item.getPushId())
            .pushCode(item.getPushCode())
            .createId(item.getCreateId())
            .field1(item.getField1())
            .field2(item.getField2())
            .field3(item.getField3())
            .field4(item.getField4())
            .field5(item.getField5())
            .field6(item.getField6())
            .field7(item.getField7())
            .field8(item.getField8())
            .field9(item.getField9())
            .field10(item.getField10())
            .build()).collect(Collectors.toList()));
        return page;
    }

    /**
     * 推送产成品入库单
     * @param list
     */
    public void pushProductReceive(List<TProductReceivePush> list) {

        if (CollectionUtil.isEmpty(list)) {
            return;
        }

        // 查询入库单明细
        List<TProductReceivePushDetails> detailList =
            tProductReceiveDetailsPushService.list(Wrappers.<TProductReceivePushDetails>lambdaQuery()
                .in(TProductReceivePushDetails::getReceiveId, list.stream()
                    .map(TProductReceivePush::getId).collect(Collectors.toList())));
        Map<Long, List<TProductReceivePushDetails>> detailMap =
            detailList.stream().collect(Collectors.groupingBy(TProductReceivePushDetails::getReceiveId));
        List<TProductReceivePush> updates = new ArrayList<>();
        for (TProductReceivePush tProductReceivePush : list) {
            try {
                ProductReceiveCreateVO vo = ProductReceiveCreateVO.builder()
                    .externalCode(tProductReceivePush.getExternalCode())
                    .voucherTypeCode(tProductReceivePush.getVoucherTypeCode())
                    .voucherDate(tProductReceivePush.getVoucherDate())
                        .busiTypeCode(tProductReceivePush.getBusiTypeCode())
                    .rdStyleCode(tProductReceivePush.getRdStyleCode())
                    .warehouseCode(tProductReceivePush.getWarehouseCode())
                    .details(detailMap.get(tProductReceivePush.getId()).stream().map(orderDetail -> ProductReceiveCreateVO.Details.builder()
                        .inventoryCode(orderDetail.getInventoryCode())
                        .rowCode(orderDetail.getRowCode())
                        .quantity(orderDetail.getQuantity())
                        .build()).collect(Collectors.toList()))
                    .build();
                TFResultVO resultVO = asyncTMService.pushArrivalCreate(vo);
                tProductReceivePush.setPushId(resultVO.getData().getId());
                tProductReceivePush.setPushCode(resultVO.getData().getCode());
                tProductReceivePush.setPushStatus(1);
                tProductReceivePush.setPushResult(resultVO.getResult());
                tProductReceivePush.setPushTime(LocalDateTime.now());
                updates.add(tProductReceivePush);
            } catch (Exception e) {
                log.error("推送T+产成品入库单异常 {}, {}", e, tProductReceivePush);
            }
        }
        if (CollectionUtil.isNotEmpty(updates)) {
            updateBatchById(updates);
        }
    }
}
